00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #ifndef _value_transfer_hpp_
00027 #define _value_transfer_hpp_
00028
00029 #include <boost/shared_array.hpp>
00030 #include <boost/static_assert.hpp>
00031
00032 #include "numeric_type_check.hpp"
00033
00034 #include "gridpack/utilities/uncopyable.hpp"
00035
00036 namespace gridpack {
00037 namespace math {
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050 template <typename FromType, typename ToType>
00051 class ValueTransfer
00052 : private utility::Uncopyable
00053 {
00054 public:
00055
00056
00057 ValueTransfer(const unsigned int& from_size, FromType* from, ToType* to = NULL)
00058 : utility::Uncopyable(),
00059 p_fromSize(from_size), p_from(from),
00060 p_to()
00061 {
00062 if (to != NULL) {
00063 p_to.reset(to, null_deleter());
00064 }
00065 }
00066
00067
00068 ~ValueTransfer(void)
00069 { }
00070
00071
00072 unsigned int size(void) const
00073 {
00074 return p_computeToSize();
00075 }
00076
00077
00078 void go(void)
00079 {
00080 this->p_setup();
00081 this->p_copy();
00082 }
00083
00084
00085 ToType *to(void)
00086 {
00087 return p_to.get();
00088 }
00089
00090 protected:
00091
00092
00093 static const unsigned int TWO = 2;
00094
00095
00096 static const bool p_isSame = boost::is_same<FromType, ToType>::value;
00097
00098
00099 const unsigned int p_fromSize;
00100
00101
00102 FromType *p_from;
00103
00104
00105 boost::shared_array<ToType> p_to;
00106
00107
00108 virtual inline unsigned int p_computeToSize(void) const;
00109
00110
00111 inline void p_setup(void);
00112
00113
00114 virtual inline void p_copy(void);
00115
00116 private:
00117
00118 BOOST_STATIC_ASSERT(TypeCheck<FromType>::OK::value);
00119 BOOST_STATIC_ASSERT(TypeCheck<ToType>::OK::value);
00120
00121
00122 struct null_deleter {
00123 void operator()(void const *p) const {}
00124 };
00125
00126
00127 };
00128
00129
00130
00131
00132
00133 template <typename FromType, typename ToType>
00134 inline unsigned int
00135 ValueTransfer<FromType, ToType>::p_computeToSize(void) const
00136 {
00137 BOOST_STATIC_ASSERT(p_isSame);
00138 return p_fromSize;
00139 }
00140
00141 template <>
00142 inline unsigned int
00143 ValueTransfer<RealType, ComplexType>::p_computeToSize(void) const
00144 {
00145 return p_fromSize/TWO;
00146 }
00147
00148 template <>
00149 inline unsigned int
00150 ValueTransfer<ComplexType, RealType>::p_computeToSize(void) const
00151 {
00152 return p_fromSize*TWO;
00153 }
00154
00155
00156
00157
00158 template <typename FromType, typename ToType>
00159 inline void
00160 ValueTransfer<FromType, ToType>::p_setup()
00161 {
00162 if (!p_to) {
00163 p_to.reset(new ToType[this->size()]);
00164 }
00165 }
00166
00167 template <>
00168 inline void
00169 ValueTransfer<RealType, RealType>::p_setup()
00170 {
00171 if (!p_to) {
00172 p_to.reset(p_from, null_deleter());
00173 }
00174 }
00175
00176 template <>
00177 inline void
00178 ValueTransfer<ComplexType, ComplexType>::p_setup()
00179 {
00180 if (!p_to) {
00181 p_to.reset(p_from, null_deleter());
00182 }
00183 }
00184
00185
00186
00187
00188
00189 template <typename FromType, typename ToType>
00190 inline void
00191 ValueTransfer<FromType, ToType>::p_copy(void)
00192 {
00193 BOOST_STATIC_ASSERT(p_isSame);
00194 if (p_from != p_to.get())
00195 std::copy(p_from, p_from + p_fromSize, p_to.get());
00196 }
00197
00198 template <>
00199 inline void
00200 ValueTransfer<RealType, ComplexType>::p_copy(void)
00201 {
00202 unsigned int fidx(0), tidx(0);
00203 for (fidx = 0; fidx < p_fromSize; fidx += TWO, ++tidx) {
00204 p_to.get()[tidx] = ComplexType(p_from[fidx], p_from[fidx+1]);
00205 }
00206 }
00207
00208 template <>
00209 inline void
00210 ValueTransfer<ComplexType, RealType>::p_copy(void)
00211 {
00212 unsigned int fidx(0), tidx(0);
00213 for (fidx = 0; fidx < p_fromSize; ++fidx, tidx += TWO) {
00214 p_to.get()[tidx] = std::real(p_from[fidx]);
00215 p_to.get()[tidx+1] = std::imag(p_from[fidx]);
00216 }
00217 }
00218
00219
00220
00221
00222 template <typename FromType, typename ToType>
00223 class ValueTransferToLibrary
00224 : public ValueTransfer<FromType, ToType>
00225 {
00226 public:
00227
00228
00229 ValueTransferToLibrary(const unsigned int& from_size, FromType* from, ToType* to = NULL)
00230 : ValueTransfer<FromType, ToType>(from_size, from, to)
00231 {}
00232
00233
00234 ~ValueTransferToLibrary(void) {}
00235
00236 protected:
00237
00238
00239 inline unsigned int p_computeToSize(void) const;
00240
00241
00242 inline void p_copy(void);
00243 };
00244
00245
00246
00247
00248 template <typename FromType, typename ToType>
00249 inline unsigned int
00250 ValueTransferToLibrary<FromType, ToType>::p_computeToSize(void) const
00251 {
00252 return ValueTransfer<FromType, ToType>::p_computeToSize();
00253 }
00254
00255 template <>
00256 inline unsigned int
00257 ValueTransferToLibrary<RealType, ComplexType>::p_computeToSize(void) const
00258 {
00259 return p_fromSize;
00260 }
00261
00262
00263
00264
00265
00266 template <typename FromType, typename ToType>
00267 inline void
00268 ValueTransferToLibrary<FromType, ToType>::p_copy(void)
00269 {
00270 ValueTransfer<FromType, ToType>::p_copy();
00271 }
00272
00273
00274 template <>
00275 inline void
00276 ValueTransferToLibrary<RealType, ComplexType>::p_copy(void)
00277 {
00278 unsigned int fidx(0), tidx(0);
00279 for (fidx = 0; fidx < p_fromSize; ++fidx, ++tidx) {
00280 p_to.get()[tidx] = p_from[fidx];
00281 }
00282 }
00283
00284
00285
00286
00287
00288 template <typename FromType, typename ToType>
00289 class ValueTransferFromLibrary
00290 : public ValueTransfer<FromType, ToType>
00291 {
00292 public:
00293
00294
00295 ValueTransferFromLibrary(const unsigned int& from_size, FromType* from, ToType* to = NULL)
00296 : ValueTransfer<FromType, ToType>(from_size, from, to)
00297 {}
00298
00299
00300 ~ValueTransferFromLibrary(void) {}
00301
00302 protected:
00303
00304
00305 inline unsigned int p_computeToSize(void) const;
00306
00307
00308 inline void p_copy(void);
00309 };
00310
00311
00312
00313
00314 template <typename FromType, typename ToType>
00315 inline unsigned int
00316 ValueTransferFromLibrary<FromType, ToType>::p_computeToSize(void) const
00317 {
00318 return ValueTransfer<FromType, ToType>::p_computeToSize();
00319 }
00320
00321 template <>
00322 inline unsigned int
00323 ValueTransferFromLibrary<ComplexType, RealType>::p_computeToSize(void) const
00324 {
00325 return p_fromSize;
00326 }
00327
00328
00329
00330
00331
00332 template <typename FromType, typename ToType>
00333 inline void
00334 ValueTransferFromLibrary<FromType, ToType>::p_copy(void)
00335 {
00336 ValueTransfer<FromType, ToType>::p_copy();
00337 }
00338
00339
00340 template <>
00341 inline void
00342 ValueTransferFromLibrary<ComplexType, RealType>::p_copy(void)
00343 {
00344 unsigned int fidx(0), tidx(0);
00345 for (fidx = 0; fidx < p_fromSize; ++fidx, ++tidx) {
00346 p_to.get()[tidx] = std::real(p_from[fidx]);
00347 }
00348 }
00349
00350
00351
00352
00353
00354 template <typename FromType, typename ToType>
00355 class MatrixValueTransferToLibrary
00356 : public ValueTransferToLibrary<FromType, ToType>
00357 {
00358 public:
00359
00360
00361 MatrixValueTransferToLibrary(const unsigned int& from_size,
00362 FromType* from, ToType* to = NULL)
00363 : ValueTransferToLibrary<FromType, ToType>(from_size, from, to)
00364 {}
00365
00366
00367
00368 ~MatrixValueTransferToLibrary(void) {}
00369
00370 protected:
00371
00372
00373 inline unsigned int p_computeToSize(void) const;
00374
00375
00376 inline void p_copy(void);
00377
00378 };
00379
00380
00381
00382
00383 template <typename FromType, typename ToType>
00384 inline unsigned int
00385 MatrixValueTransferToLibrary<FromType, ToType>::p_computeToSize(void) const
00386 {
00387 return ValueTransferToLibrary<FromType, ToType>::p_computeToSize();
00388 }
00389
00390 template <>
00391 inline unsigned int
00392 MatrixValueTransferToLibrary<ComplexType, RealType>::p_computeToSize(void) const
00393 {
00394 return p_fromSize*TWO*TWO;
00395 }
00396
00397
00398
00399
00400 template <typename FromType, typename ToType>
00401 inline void
00402 MatrixValueTransferToLibrary<FromType, ToType>::p_copy(void)
00403 {
00404 ValueTransferToLibrary<FromType, ToType>::p_copy();
00405 }
00406
00407 template <>
00408 inline void
00409 MatrixValueTransferToLibrary<ComplexType, RealType>::p_copy(void)
00410 {
00411 unsigned int fidx(0), tidx(0);
00412 for (; fidx < p_fromSize; ++fidx) {
00413 ComplexType x(p_from[fidx]);
00414 p_to.get()[tidx] = std::real(x); ++tidx;
00415 p_to.get()[tidx] = -std::imag(x); ++tidx;
00416 p_to.get()[tidx] = std::imag(x); ++tidx;
00417 p_to.get()[tidx] = std::real(x); ++tidx;
00418 }
00419 }
00420
00421
00422
00423
00424 template <typename FromType, typename ToType>
00425 class MatrixValueTransferFromLibrary
00426 : public ValueTransferFromLibrary<FromType, ToType>
00427 {
00428 public:
00429
00430
00431 MatrixValueTransferFromLibrary(const unsigned int& from_size,
00432 FromType* from, ToType* to = NULL)
00433 : ValueTransferFromLibrary<FromType, ToType>(from_size, from, to)
00434 {}
00435
00436
00437
00438 ~MatrixValueTransferFromLibrary(void) {}
00439
00440 protected:
00441
00442
00443 inline unsigned int p_computeToSize(void) const;
00444
00445
00446 inline void p_copy(void);
00447
00448 };
00449
00450
00451
00452
00453 template <typename FromType, typename ToType>
00454 inline unsigned int
00455 MatrixValueTransferFromLibrary<FromType, ToType>::p_computeToSize(void) const
00456 {
00457 return ValueTransferFromLibrary<FromType, ToType>::p_computeToSize();
00458 }
00459
00460 template <>
00461 inline unsigned int
00462 MatrixValueTransferFromLibrary<RealType, ComplexType>::p_computeToSize(void) const
00463 {
00464 return p_fromSize/TWO/TWO;
00465 }
00466
00467
00468
00469
00470 template <typename FromType, typename ToType>
00471 inline void
00472 MatrixValueTransferFromLibrary<FromType, ToType>::p_copy(void)
00473 {
00474 ValueTransferFromLibrary<FromType, ToType>::p_copy();
00475 }
00476
00477 template <>
00478 inline void
00479 MatrixValueTransferFromLibrary<RealType, ComplexType>::p_copy(void)
00480 {
00481 unsigned int fidx(0), tidx(0);
00482 for (; fidx < p_fromSize; fidx += TWO*TWO, ++tidx) {
00483 ComplexType x(p_from[fidx], -p_from[fidx+1]);
00484 p_to.get()[tidx] = x;
00485 }
00486 }
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500 template <typename ScalarType, typename LibraryType>
00501 struct storage_size
00502 : boost::mpl::if_<
00503 typename boost::mpl::and_<
00504 boost::is_same<ScalarType, ComplexType>,
00505 boost::is_same<LibraryType, RealType> >::type,
00506 boost::mpl::int_<2>,
00507 boost::mpl::int_<1>
00508 >::type
00509 {};
00510
00511
00512
00513
00514
00515
00516 }
00517 }
00518
00519
00520
00521 #endif